
package estacionamento;

import java.sql.*; 
import java.util.ArrayList;
import java.sql.DriverManager; 
import java.text.SimpleDateFormat;

public class Conexao 
{
    //importar bibliotecas 'mysql-connector-java-5.1.6-bin.jar' e 'postgresql-9.1-901.jdbc3.jar'
    //ja adicionado
    
    private static final String driver = "org.postgresql.Driver";
    private static final String host = "dev.ct.utfpr.edu.br";
    private static final String port = "5432"; //porta padrao
    private static final String database = "aluno10"; 
    private static final String user = "aluno10"; 
    private static final String password = "aluno10"; 
    private static Connection conn;
    
    public static void conecta() throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException
    {
        Class.forName(driver).newInstance();
        
        String url = "jdbc:postgresql://" + host + ":" + port + "/" + database;
        
        //tenta estabelecer conexao
        try
        {
            System.out.print("estabelecendo conexão em: ");
            System.out.println(url+"/"+user+"/"+password);
            conn = DriverManager.getConnection(url,user,password);
            String q = conn.toString();
            System.out.println(q);
            System.out.println("conectado.");         
        }
        catch(Exception ex)
        {
            System.err.print("erro ao montar conexão.");
            if(conn == null)
            {
                System.out.println("conexão nula");
            }
        }
        
        defineSchema();
        
        System.out.println("faça os comandinhos LOL");
        
        
    }
    
    static void defineSchema() throws SQLException
    {
        Statement stmt = conn.createStatement();
        stmt.execute("SET search_path TO bogads, public;");
    }
    
    //ordenação por cpf, nome, endereco, tipo, numero de vagas ou veiculo
    static void listaClientes(String ordem) throws SQLException 
    {
        int i = 0;
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM cliente ORDER BY " + ordem);
        while (rs.next()) 
        {
            System.out.println(String.format("%08d %s", rs.getInt("codigo"),rs.getString("nome")));
            i++;
        }
        System.out.println(i + " clientes cadastrados");
    }
    
     static Cliente buscaCliente (String cpf) throws SQLException
    {
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM cliente WHERE cpf = '" + cpf + "'");
        Cliente c = new Cliente();
        
        while(rs.next()){
           
            c.setCpf(rs.getString("cpf"));
            c.setEndereco(rs.getString("endereco"));
            c.setNome(rs.getString("nome"));
            c.setTipo("tipo");
        }
   
        return c;
    }
     
     static int numeroVeiculos(String cpf) throws SQLException
     {
         int n=0;
         
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM veiculo WHERE cpf = '" + cpf + "'");
         
         while(rs.next())
         {
             n = rs.getInt("count");
         }
         
         return n;
     }
     
     static int numeroVagasReservadas(String cpf) throws SQLException
     {
         int n=0;
         
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM vaga WHERE cpf = '" + cpf + "'");
         
         while(rs.next())
         {
             n = rs.getInt("count");
         }
         
         return n;
     }
    
    static void insereCliente(String cpf, String nome, String endereco, String tipo) throws SQLException 
    {
        String comando = "INSERT INTO cliente(cpf, nome, endereco, tipo) VALUES (?, ?, ?, ?)";
        
        PreparedStatement ps = conn.prepareStatement(comando);     
        ps.setString(1, cpf);
        ps.setString(2, nome);
        ps.setString(3, endereco);
        ps.setString(4, tipo);
        ps.executeUpdate();
    }
    
    static void excluiCliente(String cpf) throws SQLException 
    {
        PreparedStatement ps = conn.prepareStatement("DELETE FROM cliente WHERE cpf = ?");
        ps.setString(1, cpf);
        ps.executeUpdate();
    }
    
    static void excluiTodosClientes() throws SQLException 
    {
        Statement stmt = conn.createStatement();
        int n = stmt.executeUpdate("DELETE FROM cliente");
        System.out.println(n + " clientes excluidos");
    }
    
    static void insereVeiculo(String placa, String fabricante, String marca, String modelo, String porte, String cpf) throws SQLException 
    {
        String comando = "INSERT INTO veiculo (placa, fabricante, marca, modelo, porte, cliente_cpf) VALUES (?, ?, ?, ?, ?, ?)";
        PreparedStatement ps = conn.prepareStatement(comando);
        ps.setString(1, placa);
        ps.setString(2, fabricante);
        ps.setString(3, marca);
        ps.setString(4, modelo);
        ps.setString(5, porte);
        ps.setString(6, cpf);
        ps.executeUpdate();
    }
    
    static Veiculo buscaVeiculo(String placa) throws SQLException
    {
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM veiculo WHERE placa = '" + placa + "'");
        Veiculo v = new Veiculo();
        
        while(rs.next()){
           
            v.setFabricante(rs.getString("fabricante"));
            v.setMarca(rs.getString("marca"));
            v.setModelo(rs.getString("modelo"));
            v.setPlaca(rs.getString("placa"));
            v.setPorte(rs.getString("porte"));
        }
   
        return v;
    }
    
  
    
    //ordenação por placa, fabricante, modelo, porte ou marca
    static void listaVeiculos(String ordem) throws SQLException 
    {   Veiculo v = new Veiculo();
        ArrayList<Veiculo> veiculos = new ArrayList();
        int i = 0;
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM veiculo ORDER BY " + ordem);
        while (rs.next()) 
        {
            v.setFabricante(rs.getString("fabricante"));
            v.setMarca(rs.getString("marca"));
            v.setModelo(rs.getString("modelo"));
            v.setPlaca(rs.getString("placa"));
            v.setPorte(rs.getString("porte"));
            veiculos.add(v);
            //System.out.println(String.format("%08d %s", rs.getInt("codigo"),rs.getString("placa")));
            i++;
        }
        System.out.println(i + " veículos cadastrados");
    }
    
    static void excluiVeiculo(String placa) throws SQLException 
    {
        PreparedStatement ps = conn.prepareStatement("DELETE FROM veiculo WHERE placa = ?");
        ps.setString(1, placa);
        ps.executeUpdate();
    }
    
    static void excluiTodosVeiculos() throws SQLException 
    {
        Statement stmt = conn.createStatement();
        int n = stmt.executeUpdate("DELETE FROM veiculo");
        System.out.println(n + " veículos excluidos");
    }
    
    static boolean insereUsuario(String login, String senha, boolean adm, 
            String nome, String cpf,String endereco) throws SQLException 
    {
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM usuario WHERE cpf = '" + cpf + "' OR login = '" + login + "'");
        int i = 0;
        while(rs.next()){
         i++;   
        }
        if(i == 0){
          String comando = "INSERT INTO usuario (login, senha, adm, nome, cpf, endereco) VALUES (?, ?, ?, ?, ?, ?)";
        PreparedStatement ps = conn.prepareStatement(comando);
        ps.setString(1, login);
        ps.setString(2, senha);
        ps.setBoolean(3, adm);
        ps.setString(4, nome);
        ps.setString(5, cpf);
        ps.setString(6, endereco);
        ps.executeUpdate();  
            return true;
        }else{
           return false;
        }
        
    }
    
    //ordenação por login
    //incluir no cadastro de clientes?? no caso um usuário do sistema seria automaticamente
    //um cliente.
    static void listaUsuarios(String ordem) throws SQLException 
    {
        int i = 0;
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM usuario ORDER BY " + ordem);
        while (rs.next()) 
        {
            System.out.println(String.format("%08d %s", rs.getInt("codigo"),rs.getString("login")));
            i++;
        }
        System.out.println(i + " usuários cadastrados");
    }
    
    static void excluiUsuario (String login) throws SQLException 
    {
        PreparedStatement ps = conn.prepareStatement("DELETE FROM usuario WHERE login = ?");
        ps.setString(1, login);
        ps.executeUpdate();
    }
    
    
    
    static void inserePagamento(double valor) throws SQLException 
    {
        String comando = "INSERT INTO pagamento (valor) VALUES (?)";
        PreparedStatement ps = conn.prepareStatement(comando);
        ps.setDouble(1, valor);
        ps.executeUpdate();
    }
    
    //ordenação por valor ou placa
    static void listaPagamentos(String ordem) throws SQLException 
    {
        int i = 0;
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM pagamento ORDER BY " + ordem);
        while (rs.next()) 
        {
            System.out.println(String.format("%s %f", rs.getString("placa"),rs.getDouble("valor")));
            i++;
        }
        System.out.println(i + " pagamentos cadastrados");
    }
        
    static int  contaVagas() throws SQLException{
        Statement stmt = conn.createStatement();
        int i = 0;
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM vaga");
        while(rs.next()){
        i = rs.getInt("count");
        }
        return i;
    }
    
    static int  contaVagasLivres() throws SQLException{
        Statement stmt = conn.createStatement();
        int i = 0;
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM vaga WHERE ocupado = true");
        while(rs.next()){
        i = rs.getInt("count");
        }
        int total = contaVagas();
        int reservadas = contaVagasReservadas();
        int n = total - (i + reservadas);
        return n;
    }
    
    static int  contaVagasReservadas() throws SQLException{
        Statement stmt = conn.createStatement();
        int i = 0;
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM vaga WHERE reservado = true");
        while(rs.next()){
        i = rs.getInt("count");
        }
        return i;
    }
    
    //id será auto incremental?
    static void insereVaga() throws SQLException 
    {
        String comando = "INSERT INTO vaga DEFAULT VALUES";
        PreparedStatement ps = conn.prepareStatement(comando);   
        ps.executeUpdate();
    }
    
    static int estaEstacionado(String placa) throws SQLException {
        int id = 0;
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM vaga WHERE veiculo_placa = '" + placa + "'");
        while(rs.next()){
            id = rs.getInt("id");
        }
        return id;
    }
    
    static int ocupaVagaHorista(String placa) throws SQLException
    {
        int id = 0;
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM vaga WHERE ocupado = false AND reservado = false order by id");
        while(rs.next()){
            
            if(rs.getString("veiculo_placa") == null){
                id = rs.getInt("id");
                String comando = "UPDATE vaga SET ocupado = true WHERE id = " + id;
                String comando2 = "UPDATE vaga SET veiculo_placa = '" + placa + "' WHERE id = " + id;
                String comando3 = "INSERT INTO periodo VALUES(now(),null," +id + ")";
                PreparedStatement ps = conn.prepareStatement(comando); 
                PreparedStatement ps2 = conn.prepareStatement(comando2); 
                PreparedStatement ps3 = conn.prepareStatement(comando3); 
                ps.executeUpdate();
                ps2.executeUpdate();
                ps3.executeUpdate();
                break;
            }
            
        }
        return id;
        
       // ps.setInt(1, id);
       
    }
    
     static double desocupaVaga(int id) throws SQLException
    {
        String comando = "UPDATE vaga SET ocupado = false WHERE id = ?";
        String comando2 = "UPDATE vaga SET veiculo_placa = null WHERE id = " + id;
        PreparedStatement ps = conn.prepareStatement(comando);
        PreparedStatement ps2 = conn.prepareStatement(comando2);
        ps.setInt(1, id);
        ps.executeUpdate();
        ps2.executeUpdate();
        insereHoraSaida(id);
        int totalHoras;
        totalHoras = totalHoras(id);
        double preco = calculapreco(totalHoras,id);
        excluiRegistroPeriodo(id);
        return preco;
        
        
    }
    
     static Usuario buscaUsuario(String login, String senha) throws SQLException
     {
         boolean ok;
         Usuario u = new Usuario();
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT * FROM usuario WHERE login ='" + login + "' AND senha = '" + senha + "'");
        while(rs.next()){
         u.setLogin(String.format("%s", rs.getString("login")));
         u.setSenha(String.format("%s", rs.getString("senha")));
         u.setAdm(rs.getBoolean("adm"));
        }
         return u;
         
         
     }
    
    //ajustar para que exclua todas as vagas a partir da selecionada!
    static void excluiVaga (int id) throws SQLException 
    {
        PreparedStatement ps = conn.prepareStatement("DELETE FROM vaga WHERE id = ?");
        ps.setInt(1, id);
        ps.executeUpdate();
    }
    
    static void excluiRegistroPeriodo(int id) throws SQLException{
        String comando = "DELETE FROM periodo WHERE vaga_id = " + id;
        PreparedStatement ps = conn.prepareStatement(comando);
//        ps.setInt(1, id);
        ps.executeUpdate();
    }
    
    static void insereHoraEntrada(int id) throws SQLException
    {
        String comando = "INSERT INTO periodo(hora_entrada, hora_saida, vaga_id) VALUES(now(),null,?)";
        PreparedStatement ps = conn.prepareStatement(comando);
        ps.setInt(1, id);
        ps.executeUpdate();
    }
    
    static void insereHoraSaida(int id) throws SQLException
    {
        String comando = "UPDATE periodo SET hora_saida = now() WHERE vaga_id = " + id;
        PreparedStatement ps = conn.prepareStatement(comando);
//        ps.setInt(1, id);
        ps.executeUpdate();
    }
    
    static void excluiHoras(int id) throws SQLException
    {
        String comando = "DELETE * FROM periodo WHERE id_vaga = ?";
        PreparedStatement ps = conn.prepareStatement(comando);
        ps.setInt(1, id);
        ps.executeUpdate();
    }
    static double calculapreco (int min, int id) throws SQLException
    {   double preco;
        Horario horarios = new Horario();
        String periodo = null;
        Date entrada = null;
        Date saida = null;
        double horatotal;
        Preco p = new Preco();
        p = listaPrecos();
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT hora_entrada, hora_saida FROM periodo WHERE vaga_id ="+id);
        while (rs.next())
        {
            entrada = new Date(rs.getTimestamp("hora_entrada").getTime());
            saida = new Date(rs.getTimestamp("hora_saida").getTime());
        }
        horarios = listaHorarios();
        System.out.println("hora entrada do veiculo: "+entrada.getTime());
        System.out.println("hora inicio da noite "+horarios.getInicio_noite().getTime());
     
        if(entrada.getTime() > horarios.getInicio_manha().getTime() && saida.getTime() < horarios.getFim_manha().getTime()){
            periodo = "manha";
        }
        if(entrada.getTime() > horarios.getInicio_tarde().getTime() && saida.getTime() < horarios.getFim_tarde().getTime()){
            periodo = "tarde";
        }
        if(entrada.getTime() > horarios.getInicio_noite().getTime() && saida.getTime() < horarios.getFim_noite().getTime()){
            periodo = "noite";
        }
        if(entrada.getTime() < horarios.getFim_manha().getTime() && saida.getTime() > horarios.getInicio_tarde().getTime()){
            periodo = "manha e tarde";
        }
        if(entrada.getTime() < horarios.getFim_tarde().getTime() && saida.getTime() > horarios.getInicio_noite().getTime()){
            periodo = "tarde e noite";
        }
        if(entrada.getTime() < horarios.getFim_manha().getTime() && saida.getTime() > horarios.getInicio_noite().getTime()){
            periodo = "integral";
        }
        
        if (min < 60)
        { 
            preco = p.getPreco_primeira_hora();
        }else{
            horatotal= min/60;  
            preco = p.getPreco_primeira_hora()+(p.getPreco_hora()*(horatotal-1));
        }
        System.out.println(periodo);
        if(preco > p.getPreco_any(periodo)){
            preco = p.getPreco_any(periodo);
        }
        return preco;
    }
    
    //TESTAR!!!!!!!!!!!
    static int totalHoras(int id) throws SQLException
    {
        long resultado;
        double precofinal;
        
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT hora_entrada,hora_saida FROM periodo WHERE vaga_id="+id);
        /*while (rs.next()) 
        {
            System.out.println(String.format("%08d %s", rs.getInt("codigo"),rs.getString("login")));
            i++;
        }*/
        Date entrada = null;
        Date saida = null;
        while(rs.next()){
        entrada = new Date(rs.getTimestamp("hora_entrada").getTime());
        saida = new Date(rs.getTimestamp("hora_saida").getTime());   
        }
        resultado = saida.getTime() - entrada.getTime();
        double resultado_segundos;
        int resultado_minutos;
        resultado_segundos = resultado/1000;
        resultado_minutos = (int)resultado_segundos/60;
        System.out.println(resultado_minutos);
        
        
        return resultado_minutos;
        
        
    }
    
    public static Preco listaPrecos() throws SQLException{
        Preco valores = new Preco();
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM preco");
        while(rs.next()){
            valores.setPreco_hora(rs.getDouble("preco_hora"));
            valores.setPreco_primeira_hora(rs.getDouble("preco_primeira_hora"));
            valores.setPreco_manha(rs.getDouble("preco_manha"));
            valores.setPreco_tarde(rs.getDouble("preco_tarde"));
            valores.setPreco_noite(rs.getDouble("preco_noite"));
            valores.setPreco_manha_e_tarde(rs.getDouble("preco_manha_e_tarde"));
            valores.setPreco_tarde_e_noite(rs.getDouble("preco_tarde_e_noite"));
            valores.setPreco_integral(rs.getDouble("preco_integral"));
        }
        
        return valores;
    }
    
    public static void definirPrecos(double preco_hora,double preco_manha,double preco_tarde,double preco_noite,double preco_manha_e_tarde,double preco_tarde_e_noite,double preco_integral,double preco_primeira_hora) throws SQLException{
        String comando = "UPDATE preco SET preco_hora = ?, preco_manha = ?, preco_tarde = ?, preco_noite = ?, preco_manha_e_tarde = ?, preco_tarde_e_noite = ?, preco_integral = ?, preco_primeira_hora = ?";
        PreparedStatement ps = conn.prepareStatement(comando);
        ps.setDouble(1, preco_hora);
        ps.setDouble(2, preco_manha);
        ps.setDouble(3, preco_tarde);
        ps.setDouble(4, preco_noite);
        ps.setDouble(5, preco_manha_e_tarde);
        ps.setDouble(6, preco_tarde_e_noite);
        ps.setDouble(7, preco_integral);
        ps.setDouble(8, preco_primeira_hora);
        ps.executeUpdate();
        
    }
    
    public static Horario listaHorarios() throws SQLException{
        Horario horarios = new Horario();
       
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM horario");
        while(rs.next()){
            horarios.setInicio_manha(rs.getTime("inicio_manha"));
            horarios.setInicio_tarde(rs.getTime("inicio_tarde"));
            horarios.setInicio_noite(rs.getTime("inicio_noite"));
            horarios.setFim_manha(rs.getTime("fim_manha"));
            horarios.setFim_tarde(rs.getTime("fim_tarde"));
            horarios.setFim_noite(rs.getTime("fim_noite"));
        }
        
        return horarios;
    }
    
    public static void definirHorarios(Time inicio_manha,Time inicio_tarde,Time inicio_noite,Time fim_manha,Time fim_tarde,Time fim_noite)throws SQLException{
        String comando = "UPDATE horario SET inicio_manha= ?, inicio_tarde = ?, inicio_noite = ?, fim_manha = ?, fim_tarde = ?, fim_noite = ?";
        PreparedStatement ps = conn.prepareStatement(comando);
        ps.setTime(1, inicio_manha);
        ps.setTime(2, inicio_tarde);
        ps.setTime(3, inicio_noite);
        ps.setTime(4, fim_manha);
        ps.setTime(5, fim_tarde);
        ps.setTime(6, fim_noite);
     
        ps.executeUpdate();
        
    }
    
}

   